const DateTime = @import("myzql").temporal.DateTime;
const String = @import("ztring").String;
const std = @import("std");

pub const Teacher = struct {
    Id: ?i32 = null,
    name: ?[]const u8 = null,
    phone: ?[]const u8 = null,
    tm: ?DateTime = null,
};

pub const TeacherStander = struct {
    Id: ?[]const u8 = null,
    name: ?[]const u8 = null,
    phone: ?[]const u8 = null,
    tm: ?[]const u8 = null,
};

pub fn stander_2_model(stander: *TeacherStander) Teacher {
    const iid = try std.fmt.parseInt(i32, stander.Id, 10);
    const tm = try str_2_dateTime(stander.tm.?);
    return Teacher{ .Id = iid, .name = stander.name, .phone = stander.phone, .tm = tm };
}

pub fn model_2_stander(model: *const Teacher) TeacherStander {
    const tm = model.tm.?;
    var stm = dateTime_2_str(&tm) catch unreachable;
    var buffer: [32]u8 = undefined;
    const id = String.init_with_contents(std.heap.page_allocator, std.fmt.bufPrint(&buffer, "{d}", .{model.Id.?}) catch unreachable) catch unreachable;

    return TeacherStander{ .Id = id.str(), .name = model.name, .phone = model.phone, .tm = stm.str() };
}

fn dateTime_2_str(dateTime: *const DateTime) !String {
    var s = String.init(std.heap.page_allocator);
    var data: []u8 = undefined;
    var buffer: [64]u8 = undefined;

    data = std.fmt.bufPrint(&buffer, "{d}-", .{dateTime.year}) catch unreachable;
    try s.concat(data);

    if (dateTime.month < 10) {
        data = std.fmt.bufPrint(&buffer, "0{d}-", .{dateTime.month}) catch unreachable;
    } else {
        data = std.fmt.bufPrint(&buffer, "{d}-", .{dateTime.month}) catch unreachable;
    }
    try s.concat(data);

    if (dateTime.day < 10) {
        data = std.fmt.bufPrint(&buffer, "0{d} ", .{dateTime.day}) catch unreachable;
    } else {
        data = std.fmt.bufPrint(&buffer, "{d} ", .{dateTime.day}) catch unreachable;
    }
    try s.concat(data);

    if (dateTime.hour < 10) {
        data = std.fmt.bufPrint(&buffer, "0{d}:", .{dateTime.hour}) catch unreachable;
    } else {
        data = std.fmt.bufPrint(&buffer, "{d}:", .{dateTime.hour}) catch unreachable;
    }
    try s.concat(data);

    if (dateTime.minute < 10) {
        data = std.fmt.bufPrint(&buffer, "0{d}:", .{dateTime.minute}) catch unreachable;
    } else {
        data = std.fmt.bufPrint(&buffer, "{d}:", .{dateTime.minute}) catch unreachable;
    }
    try s.concat(data);

    if (dateTime.second < 10) {
        data = std.fmt.bufPrint(&buffer, "0{d}", .{dateTime.second}) catch unreachable;
    } else {
        data = std.fmt.bufPrint(&buffer, "{d}", .{dateTime.second}) catch unreachable;
    }
    try s.concat(data);

    return s;
}

fn str_2_dateTime(st: []const u8) !DateTime {
    var s = try String.init_with_contents(std.heap.page_allocator, st);
    const items1 = try s.splitAll(" ");
    var date_str = try String.init_with_contents(std.heap.page_allocator, items1[0]);
    defer date_str.deinit();
    var time_str = try String.init_with_contents(std.heap.page_allocator, items1[1]);
    defer time_str.deinit();

    const date_items = try date_str.splitAll(":");
    const year = date_items[0];
    const month = date_items[1];
    const day = date_items[2];

    const time_items = try time_str.splitAll(":");
    const hour = time_items[0];
    const minute = time_items[1];
    const second = time_items[2];

    return DateTime{ .year = year, .month = month, .day = day, .hour = hour, .minute = minute, .second = second, .microsecond = 0 };
}
